
package com.feib.soeasy.action;

import java.util.ArrayList;
import java.util.List;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontBind;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.LocalizableMessage;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;

import com.feib.soeasy.model.ColumnDefinition;
import com.feib.soeasy.model.FormatDefinition;
import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.LabelValue;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.service.FormatDefinitionService;
import com.feib.soeasy.service.GroupService;
import com.feib.soeasy.service.PaymentService;
import com.feib.soeasy.util.UserUtil;


/**
 * @title (#)Soez9009ActionBean.java<br>
 * @description 上傳檔案定義<br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2011/1/25 create by Jimmy Liu<br>
 */
public class Soez9009ActionBean extends BaseActionBean {

    private static final String DEFAULT_JSP = "/WEB-INF/views/soez9009/soez9009.jsp";    

    /**
     * 業者代號查詢畫面
     */
    private static final String AJAX_QUERY_GROUP_JSP = "/WEB-INF/views/soez9009/groupPopUpList.jsp";

    /**
     * [業者代號]改變後觸發重製[收款類別]選項結果
     */
    private static final String AJAX_FORMT_DEF_OPTIONS_JSP = "/WEB-INF/views/soez9009/formatDefinitionOptions.jsp";
    

    private static List<ColumnDefinition> headerPayerColumnsOptions;
    static
    {
        headerPayerColumnsOptions = new ArrayList<ColumnDefinition>();
        
        ColumnDefinition cd = new ColumnDefinition();
        cd.setColumnName("payerNo");
        cd.setColumnTitle("繳款人編號");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerName");
        cd.setColumnTitle("姓名");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerEmail");
        cd.setColumnTitle("繳款人Email");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerTelNo");
        cd.setColumnTitle("電話號碼");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerCellNo");
        cd.setColumnTitle("手機號碼");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("levelGround");
        cd.setColumnTitle("坪數");
        cd.setColumnType("2");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("parkingCount");
        cd.setColumnTitle("車位數");
        cd.setColumnType("2");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("houseNo");
        cd.setColumnTitle("門牌號碼");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerAddress");
        cd.setColumnTitle("聯絡地址");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerMemo");
        cd.setColumnTitle("備註");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerPayerColumnsOptions.add(cd);
        
        /* 無客至化欄位
        for(int i=0; i <=20; i++)
        {
            cd = new ColumnDefinition();
            cd.setColumnName("attribute"+i);
            cd.setColumnTitle("客製化"+i);
            cd.setColumnType("1");
            cd.setRequired(Boolean.FALSE);
            cd.setHeader(Boolean.TRUE);
            headerPayerColumnsOptions.add(cd);
        }
        */
    }
    
    private static List<ColumnDefinition> headerColumnsOptionsSchool;
    static
    {
        headerColumnsOptionsSchool = new ArrayList<ColumnDefinition>();
        
        ColumnDefinition cd = new ColumnDefinition();
        cd.setColumnName("virtualAccount");
        cd.setColumnTitle("繳費帳號");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("totalAmount");
        cd.setColumnTitle("應繳合計");
        cd.setColumnType("2");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("totalLoanableAmount");
        cd.setColumnTitle("減免後金額");
        cd.setColumnType("2");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
               
        cd = new ColumnDefinition();
        cd.setColumnName("payDue");
        cd.setColumnTitle("繳費期限");
        cd.setColumnType("3");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentName");
        cd.setColumnTitle("帳單名稱");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        /*
        cd = new ColumnDefinition();
        cd.setColumnName("period");
        cd.setColumnTitle("期別");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        */
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerId");
        cd.setColumnTitle("繳款人編號");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerName");
        cd.setColumnTitle("繳款人姓名");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerEmail");
        cd.setColumnTitle("繳款人E-mail");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerBirthday");
        cd.setColumnTitle("繳款人生日");
        cd.setColumnType("3");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerAddress");
        cd.setColumnTitle("繳款人住址");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerTelNo");
        cd.setColumnTitle("繳款人電話");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerCellNo");
        cd.setColumnTitle("繳款人手機");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("studentId");
        cd.setColumnTitle("學號");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("academicYear");
        cd.setColumnTitle("學年度");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("semester");
        cd.setColumnTitle("學期");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("department");
        cd.setColumnTitle("科系所");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("grade");
        cd.setColumnTitle("年級");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("classNo");
        cd.setColumnTitle("班級/班別");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("seatNo");
        cd.setColumnTitle("座號");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentNote1");
        cd.setColumnTitle("注意事項");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentNote2");
        cd.setColumnTitle("最新消息");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentNote3");
        cd.setColumnTitle("備註");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptionsSchool.add(cd);
        
        for(int i=1; i <=20; i++)
        {
            cd = new ColumnDefinition();
            cd.setColumnName("attribute"+i);
            cd.setColumnTitle("客製化"+i);
            cd.setColumnType("1");
            cd.setRequired(Boolean.FALSE);
            cd.setHeader(Boolean.TRUE);
            headerColumnsOptionsSchool.add(cd);
        }
    }
    
    private static List<ColumnDefinition> headerColumnsOptions;
    static
    {
        headerColumnsOptions = new ArrayList<ColumnDefinition>();
        
        ColumnDefinition cd = new ColumnDefinition();
        cd.setColumnName("virtualAccount");
        cd.setColumnTitle("繳費帳號");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("totalAmount");
        cd.setColumnTitle("應繳合計");
        cd.setColumnType("2");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("totalLoanableAmount");
        cd.setColumnTitle("減免後金額");
        cd.setColumnType("2");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
               
        cd = new ColumnDefinition();
        cd.setColumnName("payDue");
        cd.setColumnTitle("繳費期限");
        cd.setColumnType("3");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentName");
        cd.setColumnTitle("帳單名稱");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("period");
        cd.setColumnTitle("期別");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerId");
        cd.setColumnTitle("繳款人識別ID");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerName");
        cd.setColumnTitle("繳款人姓名");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerEmail");
        cd.setColumnTitle("繳款人E-mail");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerBirthday");
        cd.setColumnTitle("繳款人生日");
        cd.setColumnType("3");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerTelNo");
        cd.setColumnTitle("繳款人電話");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerCellNo");
        cd.setColumnTitle("繳款人手機");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        
        cd = new ColumnDefinition();
        cd.setColumnName("payerAddress");
        cd.setColumnTitle("繳款人住址");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentNote1");
        cd.setColumnTitle("注意事項");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentNote2");
        cd.setColumnTitle("最新消息");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("paymentNote3");
        cd.setColumnTitle("備註");
        cd.setColumnType("1");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.TRUE);
        headerColumnsOptions.add(cd);
        
        for(int i=1; i <=20; i++)
        {
            cd = new ColumnDefinition();
            cd.setColumnName("attribute"+i);
            cd.setColumnTitle("客製化"+i);
            cd.setColumnType("1");
            cd.setRequired(Boolean.FALSE);
            cd.setHeader(Boolean.TRUE);
            headerColumnsOptions.add(cd);
        }
    }
    
    private static List<ColumnDefinition> itemColumnsOptions;
    static
    {
        itemColumnsOptions = new ArrayList<ColumnDefinition>();
        
        ColumnDefinition cd = new ColumnDefinition();
        cd.setColumnName("itemName");
        cd.setColumnTitle("繳費項目");
        cd.setColumnType("1");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.FALSE);
        itemColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("amount");
        cd.setColumnTitle("金額");
        cd.setColumnType("2");
        cd.setRequired(Boolean.TRUE);
        cd.setHeader(Boolean.FALSE);
        itemColumnsOptions.add(cd);
        
        cd = new ColumnDefinition();
        cd.setColumnName("accounts");
        cd.setColumnTitle("會計科目");
        cd.setColumnType("2");
        cd.setRequired(Boolean.FALSE);
        cd.setHeader(Boolean.FALSE);
        itemColumnsOptions.add(cd);
        
        for(int i=1; i <=10; i++)
        {
            cd = new ColumnDefinition();
            cd.setColumnName("attribute"+i);
            cd.setColumnTitle("客製化"+i);
            cd.setColumnType("1");
            cd.setRequired(Boolean.FALSE);
            cd.setHeader(Boolean.FALSE);
            itemColumnsOptions.add(cd);
        }
    }
    
    @ValidateNestedProperties({
        @Validate(field="formatDefinitionPk", required=true, on={"doQuery"})
    })
    private FormatDefinition qryFormatDefinition;
    
    private FormatDefinition editFormatDefinition;
    
    private List<ColumnDefinition> editHeaderColumnDefinitions;
    
    private List<ColumnDefinition> editItemColumnDefinitions;

    /**
     * 帳單業者查詢條件
     */
    private Group qryGroup;

    /**
     * 帳單業者查詢結果
     */
    private PaginatedList<Group> queryGroupResult;

    /**
     * 收款類別選單
     */
    private List<LabelValue> formatDefinitionoOptions;

    @SpringBean("groupService")
    private GroupService groupService;
    
    @SpringBean("formatDefinitionService")
    private FormatDefinitionService formatDefinitionService;

    @SpringBean("paymentService")
    private PaymentService paymentService;
    
    private String message;
    
    @DontBind
    @DefaultHandler
    public Resolution doDefault()
    {
        logger.debug("Enter doDefault mehtod.");
        return new ForwardResolution(DEFAULT_JSP); 
    }
    
    public Resolution doQuery()
    {
        logger.debug("Enter doQuery mehtod.");
        try
        {
            this.editFormatDefinition = formatDefinitionService.queryByPk(this.qryFormatDefinition.getFormatDefinitionPk());
            if (null != this.editFormatDefinition)
            {
                this.qryFormatDefinition = this.editFormatDefinition;
                
                sortColumns();                
            }
        }
        catch (Exception e) {
            this.editFormatDefinition = null;
            logger.error("上傳檔案定義查詢失敗", e);
        }
        return new ForwardResolution(DEFAULT_JSP); 
    }
    
    private void sortColumns()
    {
        this.editHeaderColumnDefinitions = new ArrayList<ColumnDefinition>();
        this.editItemColumnDefinitions = new ArrayList<ColumnDefinition>();
        
        // 若已有轉入資料，不可刪除與異動必要欄位
        boolean canDelete =  0 == paymentService.countByFormatDefinitionPk(this.editFormatDefinition.getFormatDefinitionPk());
        
        Integer ftype = new Integer(2);
        for(ColumnDefinition cd : this.editFormatDefinition.getColumnDefinitions())
        {
            cd.setCanDelete(canDelete);
            cd.setCanModify(canDelete);
            cd.setCnaModifyLength(canDelete);
            String columnName = cd.getColumnName();
            
            if (ftype.equals(this.editFormatDefinition.getFormatType()))
            {
                if ("payerNo".equalsIgnoreCase(columnName) || "payerName".equalsIgnoreCase(columnName)
                                || "payerEmail".equalsIgnoreCase(columnName)
                                || "payerTelNo".equalsIgnoreCase(columnName)
                                || "payerCellNo".equalsIgnoreCase(columnName)
                                || "levelGround".equalsIgnoreCase(columnName)
                                || "parkingCount".equalsIgnoreCase(columnName)
                                || "houseNo".equalsIgnoreCase(columnName)
                                || "payerAddress".equalsIgnoreCase(columnName)
                                || "payerMemo".equalsIgnoreCase(columnName))
                {
                    cd.setCanModify(Boolean.FALSE);
                    cd.setCanDelete(Boolean.FALSE);
                }
            }
            else
            {
                if ("virtualAccount".equalsIgnoreCase(columnName) || "totalAmount".equalsIgnoreCase(columnName)
                                || "payDue".equalsIgnoreCase(columnName)
                                || "paymentName".equalsIgnoreCase(columnName)
                                || "totalLoanableAmount".equalsIgnoreCase(columnName)
                                || "payerEmail".equalsIgnoreCase(columnName)
                                || "payerId".equalsIgnoreCase(columnName)
                                || "payerTelNo".equalsIgnoreCase(columnName)
                                || "payerCellNo".equalsIgnoreCase(columnName)
                                || "payerName".equalsIgnoreCase(columnName)
                                || "payerBirthday".equalsIgnoreCase(columnName)
                                || "payerAddress".equalsIgnoreCase(columnName)
                                || "studentId".equalsIgnoreCase(columnName)
                                || "academicYear".equalsIgnoreCase(columnName)
                                || "semester".equalsIgnoreCase(columnName)
                                || "department".equalsIgnoreCase(columnName)
                                || "grade".equalsIgnoreCase(columnName)
                                || "classNo".equalsIgnoreCase(columnName)
                                || "seatNo".equalsIgnoreCase(columnName)
                                || "paymentNote1".equalsIgnoreCase(columnName)
                                || "paymentNote2".equalsIgnoreCase(columnName)
                                || "paymentNote3".equalsIgnoreCase(columnName)
                                || "period".equalsIgnoreCase(columnName))
                {
                    cd.setCanModify(Boolean.FALSE);
                    cd.setCanDelete(Boolean.FALSE);
                }
            }
            
            
            if (null == cd.getHeader() || cd.getHeader().booleanValue())
                this.editHeaderColumnDefinitions.add(cd);
            else
                this.editItemColumnDefinitions.add(cd);
        }
    }
    
    public Resolution doSaveColumnDefinition()
    {
        logger.debug("Enter doSaveColumnDefinition mehtod.");
        try
        {
            this.editFormatDefinition = formatDefinitionService.queryByPk(this.editFormatDefinition.getFormatDefinitionPk());
            
            List<ColumnDefinition> unSaveColumns = new ArrayList<ColumnDefinition>();
            
            unSaveColumns.addAll(this.editHeaderColumnDefinitions);
            if(this.editItemColumnDefinitions != null)
                unSaveColumns.addAll(this.editItemColumnDefinitions);
            

            List<ColumnDefinition> toDelColumns = new ArrayList<ColumnDefinition>();
            
            // step1 先更新原本既有的
            for(ColumnDefinition dbCd : this.editFormatDefinition.getColumnDefinitions())
            {
                boolean found = false;
                for(ColumnDefinition cd : unSaveColumns)
                {
                    if (null == cd )
                        continue;
                    
                    if (null == cd.getHeader())
                        cd.setHeader(Boolean.FALSE);
                    
                    if (null == cd.getQuery())
                        cd.setQuery(Boolean.FALSE);
                    
                    if (null == cd.getDisplay())
                        cd.setDisplay(Boolean.FALSE);

                    if (null == cd.getRequired())
                        cd.setRequired(Boolean.FALSE);
                    
                    if (dbCd.getColumnDefinitionPk().equals(cd.getColumnDefinitionPk()))
                    {
                        found = true;
                        dbCd.setHeader(cd.getHeader());
                        dbCd.setColumnName(cd.getColumnName());
                        dbCd.setColumnTitle(cd.getColumnTitle());
                        dbCd.setColumnType(cd.getColumnType());
                        dbCd.setBeginIndex(cd.getBeginIndex());
                        dbCd.setEndIndex(cd.getEndIndex());
                        dbCd.setQuery(cd.getQuery());
                        dbCd.setDisplay(cd.getDisplay());
                        dbCd.setRequired(cd.getRequired());
                        break;
                    }
                }
                
                if (!found)
                    toDelColumns.add(dbCd);
                    
            }
            
            // step2 刪除畫面上沒有，DB有的
            this.editFormatDefinition.getColumnDefinitions().removeAll(toDelColumns);
            
            // step3 加入畫面上有，DB沒有的，即 columnDefinitionPk 是 NULL
            for(ColumnDefinition cd : unSaveColumns)
            {
                if (null != cd && null == cd.getColumnDefinitionPk())
                {
                    cd.setFormatDefinition(this.editFormatDefinition);
                    this.editFormatDefinition.getColumnDefinitions().add(cd);
                }
            }
            
            this.editFormatDefinition = this.formatDefinitionService.save(this.editFormatDefinition);
            this.qryFormatDefinition = this.editFormatDefinition;
            sortColumns();
            
            message = "儲存成功";
            
        }
        catch (Exception e) {
            logger.error("上傳檔案定義儲存失敗", e);
            message = "儲存失敗";
            try {
                this.editFormatDefinition = formatDefinitionService.queryByPk(this.editFormatDefinition.getFormatDefinitionPk());
                this.qryFormatDefinition = this.editFormatDefinition;
            }
            catch (Exception e2) {
            }
        }
        return new ForwardResolution(DEFAULT_JSP);
    }
    
    /**
     * 帳單業者查詢
     * @return
     */
    public Resolution doAjaxQueryGroups()
    {
        logger.debug("Enter doAjaxQueryGroups mehtod.");
        try {
            //如果不是銀行端，則查詢條件要加入帳單業者限制
            if (!UserUtil.isBankGroup())
            {
                throw new Exception(new LocalizableMessage("no.authority").getMessage(getContext().getLocale()));
            }


            //USER未輸入查詢條件，所以查詢物件會是NULL(查詢物件不可為NULL)
            if (null == qryGroup)
                qryGroup = new Group();

            //呼叫服務查詢
            queryGroupResult = groupService.queryByGroupExcludeBank(qryGroup, queryGroupResult);
        }
        catch (Exception e) {
            logger.error("上傳檔案定義-帳單業者查詢錯誤(Soez9004ActionBean.doAjaxQueryGroups):", e);

            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new SimpleError("查詢錯誤！"));
            getContext().setValidationErrors(errors);
            // 回傳 錯誤 HTML fragments
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(AJAX_QUERY_GROUP_JSP);
    }

    public Resolution doAjaxGroupNoChange()
    {
        return new ForwardResolution(AJAX_FORMT_DEF_OPTIONS_JSP);
    }
    


    /**
     * @return the formatDefinitionoOptions
     */
    public List<LabelValue> getFormatDefinitionoOptions() {
        if (null == this.formatDefinitionoOptions)
        {
            //如果不是銀行端，則查詢條件要加入帳單業者限制
            if (!UserUtil.isBankGroup())
            {
                // 查詢條件
                FormatDefinition formatDefinition = new FormatDefinition();
                Group group = new Group();
                group.setGroupPk(UserUtil.getUserGroup().getGroupPk());
                formatDefinition.setGroup(group);
                formatDefinition.setDeleted(Boolean.FALSE);
                formatDefinitionoOptions = formatDefinitionService.findLabelValueByFormatDefinition(formatDefinition, false);
            }
            else
            {
                // 銀行端，看是否有群組代碼，若沒有則回傳空陣列
                if (null != this.getQryFormatDefinition() && null != this.getQryFormatDefinition().getGroup())
                {
                    // 查詢條件
                    Group dbGroup = this.groupService.findByExactGroupNo(this.getQryFormatDefinition().getGroup().getGroupNo());
                    
                  //2011/06/16 jeff Gu  start   修正    業者代號不存在時 查詢錯誤問題
                    if (null != this.getQryFormatDefinition().getGroup()&& null !=dbGroup )
                    {
                  //2011/06/16 jeff Gu  end   修正    業者代號不存在時 查詢錯誤問題       
                        this.getQryFormatDefinition().setGroup(dbGroup);
                        
                        FormatDefinition formatDefinition = new FormatDefinition();
                        Group group = new Group();
                        group.setGroupPk(this.getQryFormatDefinition().getGroup().getGroupPk());
                        formatDefinition.setGroup(group);
                        formatDefinition.setDeleted(Boolean.FALSE);
                        formatDefinitionoOptions = formatDefinitionService.findLabelValueByFormatDefinition(formatDefinition, false);
                    }
                    else
                    {
                        this.formatDefinitionoOptions = new ArrayList<LabelValue>();
                    }
                }
                else
                {
                    if (null == this.getQryFormatDefinition())
                        this.qryFormatDefinition = new FormatDefinition();
                    if (null == this.getQryFormatDefinition().getGroup())
                        this.qryFormatDefinition.setGroup(new Group());
                    this.formatDefinitionoOptions = new ArrayList<LabelValue>();                    
                }

            }

        }
        return formatDefinitionoOptions;
    }


    /**
     * @param formatDefinitionoOptions the formatDefinitionoOptions to set
     */
    public void setFormatDefinitionoOptions(List<LabelValue> formatDefinitionoOptions) {
        this.formatDefinitionoOptions = formatDefinitionoOptions;
    }

    
    /**
     * @return the qryFormatDefinition
     */
    public FormatDefinition getQryFormatDefinition() {
        return qryFormatDefinition;
    }

    
    /**
     * @param qryFormatDefinition the qryFormatDefinition to set
     */
    public void setQryFormatDefinition(FormatDefinition qryFormatDefinition) {
        this.qryFormatDefinition = qryFormatDefinition;
    }

    
    /**
     * @return the editFormatDefinition
     */
    public FormatDefinition getEditFormatDefinition() {
        return editFormatDefinition;
    }

    
    /**
     * @param editFormatDefinition the editFormatDefinition to set
     */
    public void setEditFormatDefinition(FormatDefinition editFormatDefinition) {
        this.editFormatDefinition = editFormatDefinition;
    }

    
    /**
     * @return the qryGroup
     */
    public Group getQryGroup() {
        return qryGroup;
    }

    
    /**
     * @param qryGroup the qryGroup to set
     */
    public void setQryGroup(Group qryGroup) {
        this.qryGroup = qryGroup;
    }

    
    /**
     * @return the queryGroupResult
     */
    public PaginatedList<Group> getQueryGroupResult() {
        return queryGroupResult;
    }

    
    /**
     * @param queryGroupResult the queryGroupResult to set
     */
    public void setQueryGroupResult(PaginatedList<Group> queryGroupResult) {
        this.queryGroupResult = queryGroupResult;
    }

    
    /**
     * @return the editHeaderColumnDefinitions
     */
    public List<ColumnDefinition> getEditHeaderColumnDefinitions() {
        return editHeaderColumnDefinitions;
    }

    
    /**
     * @param editHeaderColumnDefinitions the editHeaderColumnDefinitions to set
     */
    public void setEditHeaderColumnDefinitions(List<ColumnDefinition> editHeaderColumnDefinitions) {
        this.editHeaderColumnDefinitions = editHeaderColumnDefinitions;
    }

    
    /**
     * @return the editItemColumnDefinitions
     */
    public List<ColumnDefinition> getEditItemColumnDefinitions() {
        return editItemColumnDefinitions;
    }

    
    /**
     * @param editItemColumnDefinitions the editItemColumnDefinitions to set
     */
    public void setEditItemColumnDefinitions(List<ColumnDefinition> editItemColumnDefinitions) {
        this.editItemColumnDefinitions = editItemColumnDefinitions;
    }

    
    /**
     * @return the headerColumnsOptions
     */
    public List<ColumnDefinition> getHeaderColumnsOptions() {
        if (UserUtil.isSchoolGroup())
            return headerColumnsOptionsSchool;
        else if (!UserUtil.isBankGroup())
            return  headerColumnsOptions;
        
        if (null != this.editFormatDefinition && new Integer(2).equals(this.editFormatDefinition.getFormatType()))
            return headerPayerColumnsOptions;
        else if (null != this.editFormatDefinition && Group.GROUP_TYPE_SCHOOL.equals(this.editFormatDefinition.getGroup().getGroupType()))
            return headerColumnsOptionsSchool;
        else 
        {
            return  headerColumnsOptions;
        }
    }

    
    /**
     * @return the itemColumnsOptions
     */
    public List<ColumnDefinition> getItemColumnsOptions() {
        return itemColumnsOptions;
    }
    
    public String getHeaderColumnsOptionsHtml()
    {
        List<ColumnDefinition> options = getHeaderColumnsOptions();
        StringBuffer result = new StringBuffer();
        result.append("<option value=\"\">--請選擇--</option>");
        for(ColumnDefinition d: options)
        {
            result.append("<option value=\"").append(d.getColumnName()).append("\">").append(d.getColumnTitle()).append("</option>");
        }
        
        return result.toString();
    }
    
    public String getItemColumnsOptionsHtml()
    {
        List<ColumnDefinition> options = getItemColumnsOptions();
        StringBuffer result = new StringBuffer();
        result.append("<option value=\"\">--請選擇--</option>");
        for(ColumnDefinition d: options)
        {
            result.append("<option value=\"").append(d.getColumnName()).append("\">").append(d.getColumnTitle()).append("</option>");
        }
        
        return result.toString();
    }

    
    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }
}
